(function(angular) {
	'use strict';
	angular.module("fs.waf").factory("siteService", siteService);
	siteService.$inject = [ '$q', '$timeout', 'loggerFactory', '$rootScope', 'modalService', 'gridService', 'ajaxServiceFactory', 'storageService', 'arithService', '$filter'];
	function siteService($q, $timeout, loggerFactory, $rootScope, modalService, gridService, ajaxServiceFactory, storageService, arithService, $filter) {
		var ajaxService = ajaxServiceFactory.buildAjaxService({
			getLayoutConfig : {
				url : 'do/cda/site/layout',
				method : 'post'
			},
			getLocales : {
				url : 'do/cda/dataList/siteLocale',
				method : 'post'
			},
			getLocaleCodes : {
				url : 'do/cda/dataList/siteLocaleCode',
				method : 'post'
			},
			getLocaleCodesTwo : {
				url : 'do/cda/dataList/siteLocaleCodeTwo',
				method : 'post'
			},
			getCalendarCodes: {
				url : 'do/cda/dataList/getCalendarCodes',
				method : 'post'					
			}
		});
		
		function getCalendarCodes() {
			var defer = $q.defer();
			ajaxService.getCalendarCodes().then(function(response) {
				defer.resolve(response ? response : {});
			});
			return defer.promise;
		};

		function loadSiteOptions() {
			var ajaxServices = ajaxServiceFactory.buildAjaxService({
				getSiteOptions : {
					url : 'do/cda/dataList/siteOptions',
					method : 'get'
				}
			});
			var defer = $q.defer();
			ajaxServices.getSiteOptions().then(function(response) {
				var siteOptions = {};
				if (response.data) {
					angular.forEach(response.data, function(value, key) {
						var tempValue = {};
						tempValue.data = value;
						siteOptions[key] = tempValue;
					});
				}
				defer.resolve(siteOptions);
			});
			return defer.promise;
		}

		function getLocaleCodesTwo(ctrl) {
			var defer = $q.defer();
			var locCodeOptions = {
				"data" : []
			};
			ajaxService.getLocaleCodes().then(function(response) {
				if (response.data) {
					angular.forEach(response.data, function(data, index, array) {
						locCodeOptions.data.push({
							"value" : data.value,
							"label" : data.label
						});
						defer.resolve(locCodeOptions);
					});

					ctrl.localeCodesData = locCodeOptions;
				}
			}, angular.noop);
			return defer.promise;
		}

		function getLocaleOptions() {
			var defer = $q.defer();
			var localeCodeOptions = [];
			ajaxService.getLocaleCodesTwo().then(function(response) {
				if (response.data) {
					angular.forEach(response.data, function(data, index, array) {
						localeCodeOptions.push({
							"value" : data.value,
							"label" : data.label
						});
					});

					defer.resolve(localeCodeOptions);
				}
			}, angular.noop);
			return defer.promise;
		}

		function setLocaleOptions(ctrl){
			function getOptions(){
				var defer = $q.defer();
				var locaCodeOptions =[];
				ajaxService.getLocaleCodesTwo().then(function(response){
					if(response.data){
						angular.forEach(response.data, function(data, index, array){
							locaCodeOptions.push({"value" : data.value, "label" : data.label});
						});
						
					 }
					defer.resolve(locaCodeOptions);
					}, angular.noop);
				return defer.promise;
			}
			getOptions().then(function(locaCodeOptions){
				var addlc = ctrl.site.localeCodes;
				var all = locaCodeOptions;
				var langs = {
						"data" : []
					};
				if(addlc.length>0){
					for(var i=0; i<addlc.length; i++){
						for(var j=0; j<all.length; j++){
							if(addlc[i] == all[j].value){
								langs.data.push(all[j]);
							}
						}
					}
				}
				ctrl.localeOptions = langs;
			});	
		}

		function getLayoutConfig(action) {
			return ajaxService.getLayoutConfig({
				'action' : action
			});
		}

		function ediProfileTypeChanged(site) {
			site.company.companyEdiProfile.activeFlag = site.company.companyEdiProfile.activeFlag || "Y";
			site.company.companyEdiProfile.overrideSiteId = "N";
		}

		function ediFileDeliChanged(obj, form) {
			if (form.$dirty && 'C' != obj.dataStatus)
				obj.dataStatus = 'U';
		}
		function ediFileDeliCompanyTypeChanged(obj, form) {
			if(form.$dirty && 'C' != obj.dataStatus) obj.dataStatus = 'U';
			if (!obj.companyType || obj.companyType == '') {
				obj.companyType = "*";
			}
		}
		
		function glPostMgrChanged(site, formConfigs) {
			var showButton = false;
			if(formConfigs.glpostmgr && formConfigs.glpostmgr.gridConfigs){
				var gridConfigs = formConfigs.glpostmgr.gridConfigs;
				if(site.glPostMgr){
					if (gridConfigs) {
						angular.forEach(gridConfigs, function(gridConfig, key) {
							if (gridConfig.dynamicParameter && "GLPOSTMGR" == gridConfig.dynamicParameter.category &&
									site.glPostMgr == gridConfig.dynamicParameter.subCategory) {
								showButton = true;
							}
						});
					}
				}
				formConfigs.general.gridConfigs.postDynaparms.active = showButton;
			}
			
		}
		function initEdiProfile(site) {
			if (!site)
				return;
			if (!site.company)
				site.company = {};
			if (!site.company.ediProfileType)
				site.company.ediProfileType = 'N';
			if (!site.company.companyEdiProfile) {
				site.company.companyEdiProfile = {};
				site.company.companyEdiProfile.ediProfileType = site.company.companyEdiProfile.ediProfileType || site.company.ediProfileType || "N";
			}
			site.company.companyEdiProfile.ediProfileType = site.company.companyEdiProfile.ediProfileType;
			ediProfileTypeChanged(site);
		}
		
		function initSiteUserTheme(site, ctrl) {
			ctrl.changeTheme = function (){
				var siteCode = storageService.getUserInfo().siteCode;
				if (!site)
					return;
				if (!site.company)
					site.company = {};
				if (site.company.themeName) {
					if ( site.company.themeName != siteCode && site.company.themeName != "DEFAULT"){
						ctrl.otherThemeName_active = true;
					} else {
						ctrl.otherThemeName_active = false;
					} 
				}
			};
		}

		function sortDynamicParamters(dymamicParamters) {
			if (!dymamicParamters) {
				return;
			}
			dymamicParamters.sort(function(p1, p2) {
				return arithService.gt(p1.dynamicParameter.dispOrder, p2.dynamicParameter.dispOrder) ? 1 : -1;
			});
		}

		function resetDynaProperties(ctrl, layoutConfig, site) {
			site = site || ctrl.site;
			resetSelectedProperties(ctrl, layoutConfig, site);
			resetAvailableProperties(ctrl, layoutConfig, site);
		}

		function resetSelectedProperties(ctrl, layoutConfig, site) {
			if (!site.siteProps) {
				site.siteProps = [];
			}
			if (site.dynamicParams) {
				angular.forEach(site.dynamicParams, function(dynamicParam, key) {
					// some new add prop or exist prop, then remove, also commit to server but value is empty, so need add '&& dynamicParam.value' to check
					// if value is empty, need in availableProperties
					if (dynamicParam.subCategory == 'CUSTOMERPROFILE' && dynamicParam.value) {
						site.siteProps.push(dynamicParam);
					}
				});
			}

			//
			if (ctrl.siteOld) {
				if (!ctrl.siteOld.siteProps) {
					ctrl.siteOld.siteProps = [];
				}
				if (ctrl.siteOld.dynamicParams) {
					angular.forEach(ctrl.siteOld.dynamicParams, function(dynamicParam, key) {
						// some new add prop or exist prop, then remove, also commit to server but value is empty, so need add '&& dynamicParam.value' to check
						if (dynamicParam.category == 'CUSTOMERPROFILE' && dynamicParam.value) {
							// change, build some dynaparm define
							var corProf = angular.copy(dynamicParam);
							// need dynamicParameter.name and dynamicParameter.dispKey
							corProf.dynamicParameter = angular.copy(dynamicParam);
							// // value is such as dynamicParams.CDA_DYNAPARM2.value
							// corProf.dynamicParams = {};
							// corProf.dynamicParams[dynamicParam.name] = dynamicParam;
							// corProf.model = 'dynamicParams.'+ dynamicParam.name +'.value';
							ctrl.siteOld.siteProps.push(corProf);
						}
					});
				}
			}
		}

		function resetAvailableProperties(ctrl, layoutConfig, site) {
			// change layoutConfig, get subCata 'CUSTOMERPROFILE'
			var i, dynaParm, hasDyna, siteProp, corProf, custProfAvaiProps = [];
			var formConfigs = layoutConfig.formConfigs || layoutConfig.data.formConfigs;
			var gridConfigs = formConfigs.custProfile.gridConfigs;
			if (gridConfigs) {
				angular.forEach(gridConfigs, function(gridConfig, key) {
					if (gridConfig.dynamicParameter && gridConfig.dynamicParameter.subCategory == 'CUSTOMERPROFILE') {
						dynaParm = angular.copy(gridConfig);
						hasDyna = false;
						if (site.siteProps && site.siteProps.length > 0) {
							for (i = 0; i < site.siteProps.length; i++) {
								siteProp = site.siteProps[i];
								if ($filter("encode")(siteProp.id) == $filter("encode")(dynaParm.dynamicParameter.id)) {
									hasDyna = true;
									delete siteProp.label;
									// change
									corProf = dynaParm;
									corProf.dynamicParams = {};
									corProf.dynamicParams[siteProp.name] = siteProp;
									// only for update verify
									corProf.primaryKey = siteProp.primaryKey;
									corProf.value = siteProp.value;
									site.siteProps[i] = corProf;
									break;
								}
							}
						}
						if (!hasDyna)
							custProfAvaiProps.push(dynaParm);
						// this will in tab cust Profile, not show other place
						gridConfig.show = false;
					}
				});
			}
			// some has value but not has layout dynaparm, need clear
			if (ctrl.site.siteProps && ctrl.site.siteProps.length > 0) {
				for (var i = ctrl.site.siteProps.length - 1; i >= 0 ; i--) {
					var siteProp = ctrl.site.siteProps[i];
					if (!siteProp.dynamicParams) {
						ctrl.site.siteProps.splice(i, 1);
					}
				}
			}
			ctrl.availableProperties = custProfAvaiProps;

			sortDynamicParamters(site.siteProps);
			sortDynamicParamters(ctrl.availableProperties);
		}
		
		function filterNotifyTpl(ctrl, site){
			if(site.eventSearchCriteria && site.eventSearchCriteria.list != null){
				var notifyTpls = site.eventSearchCriteria.list ||[];
				var notifyTypes;
				if(notifyTpls.length >0){
					angular.forEach(notifyTpls, function (notifyTpl, key){
						notifyTypes = notifyTpl.notifyTypes;
						var notifyTypesDesc = "";
						angular.forEach(notifyTypes, function (type, key){
							notifyTypesDesc += "," + $filter('translate')('label.notify.' + type.toLowerCase()) ;
						});
					});
				}
			}
		}

		function initSiteOptionData(ctrl, siteOptions) {
			ctrl.ccyOptions = siteOptions.ccyOptions;
			ctrl.countryOptions = siteOptions.countryOptions;
			ctrl.timezoneOptions = siteOptions.timezoneOptions;
			ctrl.bankStatusOptions = siteOptions.bankStatusOptions;
			ctrl.bizDateCalcOptions = siteOptions.bizDateCalcOptions;
			ctrl.yesOrNoOptions = siteOptions.yesOrNoOptions;
			ctrl.psiteFlagOptions = siteOptions.yesOrNoOptions.data;
			ctrl.sitesOptions = siteOptions.sitesOptions;
			ctrl.companyEdiFileTypeOptions = siteOptions.companyEdiFileTypeOptions;
			ctrl.overrideSiteIdOptions = siteOptions.yesOrNoOptions;
			ctrl.themeNameOptions = siteOptions.themeNameOptions;
			ctrl.glPostMgrOptions = siteOptions.glPostMgrOptions;
			ctrl.sitetplIdOptions = siteOptions.sitetplIdOptions;
			ctrl.dataStatusOptions = siteOptions.dataStatusOptions;
			ctrl.ediProfileTypeOptions = siteOptions.ediProfileTypeOptions;
			ctrl.glSystemOptions = siteOptions.glSystem;
			//isSuperBank flag
			ctrl.isSuperBank = siteOptions.isSuperBankFlag;
			ctrl.notifyTypeOptions = getNotifyTypes().data;
			ctrl.localCodeOptions = siteOptions.localeOptions.data;
		}
		
		function getNotifyTypes(){
			return {
				"data" : [ {
					"label" : "label.notify.email",
					"value" : "E"
				},{
					"value" : "F",
					"label" : "label.notify.fax"
				}, {
					"value" : "M",
					"label" : "label.notify.mail"
				} , {
					"value" : "C",
					"label" : "label.notify.phone-call"
				} , {
					"value" : "X",
					"label" : "label.notify.mobile-short-text-message"
				} ]
			};
		}
		
		function searchEvents(ctrl, eventSearchCriteria) {
			var defer = $q.defer();
			eventSearchCriteria = eventSearchCriteria || ctrl.eventSearchCriteria;
			eventSearchCriteria.list = [];
			eventSearchCriteria.filterServiceCodes = eventSearchCriteria.filterServiceCodes || [];
			if (eventSearchCriteria.filterServiceCodes.length > 0) {
				eventSearchCriteria.notifyFlag = 'Y';
				ctrl.authService.searchDocEvents(eventSearchCriteria).then(function(response) {
					angular.merge(eventSearchCriteria, response.data);
					gridService.updateGridOptions(eventSearchCriteria, ctrl.eventGridOptions);
					defer.resolve(eventSearchCriteria);
				}, function() {
					defer.resolve(eventSearchCriteria);
				});
			} else {
				defer.resolve(eventSearchCriteria);
			}
			return defer.promise;
		}
		
		function initReport($scope, ctrl, updateProcessFlag ) {
			// init serviceCode select
			ctrl.siteReport = {};
			ctrl.serviceCodeOptions = {data:[]};
			ctrl.eventSearchCriteria.filterServiceCodes = [];
			$scope.$watch('vm.site.company.services', function(services) {
				if (services) {
					ctrl.serviceCodeOptions.data = [];
					ctrl.eventSearchCriteria.filterServiceCodes = [];
					for (var i = 0; i < services.length; i++) {
						var service = services[i];
//						if (service.dataStatus == 'D') continue;
						var option = {
								label: $filter('encode')(service.serviceCode) + " - " + service.serviceName,
								value: $filter('encode')(service.serviceCode)
						};
						ctrl.serviceCodeOptions.data.push(option);
						ctrl.eventSearchCriteria.filterServiceCodes.push(option.value);
					}
					searchEvents(ctrl, ctrl.eventSearchCriteria);
				}
			}, true);
			$scope.$watch('vm.siteReport.serviceCode', function(serviceCode) {
				if (serviceCode) {
					ctrl.site.siteReportsTmp = ctrl.site['siteReports' + $filter('encode')(serviceCode)] || [];
					if(ctrl.siteOld) ctrl.siteOld.siteReportsTmp = ctrl.siteOld['siteReports' + $filter('encode')(serviceCode)] || [];
				} else {
					ctrl.site.siteReportsTmp = [];
					if(ctrl.siteOld) ctrl.siteOld.siteReportsTmp = [];
				}
			});
			
			ctrl.addReport = function(row) {
				return $q(function(resolved, rejected){
					if (!ctrl.siteReport.serviceCode) {
						modalService.openErrorDialogs({
							messages : [ "js.info.site.servicecode-need-first-select" ]
						});
						return;
					}
					if (!ctrl.site.siteCode ) {
						modalService.openErrorDialogs({
							messages : [ "js.info.site.sitecode-need-first-select" ]
						});
						return;
					}
					var params = {};
					params.companyRpt = {report : {}};
					params.companyRpt.companyCode = $filter('encode')(ctrl.site.siteCode);
					params.companyRpt.report.serviceCode = ctrl.siteReport.serviceCode;
					params.companyRpt.report.companyTypeList= [ "BANK" ];
					params.filterReportCodes = [];
					angular.forEach(ctrl.site.siteReports, function(report, index) {
						params.filterReportCodes.push($filter('encode')(report.reportCode));			//report.reportCode
					});
					params.multiSelect = true;
					
					modalService.openCustomDialogs({
						   'title': 'Site Report',
						   'dialogsModule' : 'cda.report',
						   'params': params,
						   'btnCallback' : {
								'ok' : function(selectedRows) {
									if (!selectedRows || selectedRows.length == 0) {
										modalService.openErrorDialogs({
											messages : [ "js.info.common.item-need-first-select" ]
										});
										return false;
									}
									if (!ctrl.site.siteReports) {								
										ctrl.site.siteReports = [];
									}
									if (!ctrl.site['siteReports' + $filter('encode')(ctrl.siteReport.serviceCode)]) {
										ctrl.site['siteReports' + $filter('encode')(ctrl.siteReport.serviceCode)] = [];
									}
									
									
									angular.forEach(selectedRows, function(selectedRow, index) {
										selectedRow.report = selectedRow.report ||{};
										selectedRow.report.reportName = selectedRow.reportName;
										selectedRow.report.reportTitle = selectedRow.reportTitle;
										selectedRow.report.reportSubtitle = selectedRow.reportSubtitle;
										selectedRow.report.reportMode = selectedRow.reportMode;
										selectedRow.report.serviceCode = selectedRow.serviceCode;
										selectedRow.dataStatus = 'C';
										selectedRow.companyCode = ctrl.site.siteCode;//need has encode
										ctrl.site.siteReports.push(selectedRow);
										ctrl.site['siteReports' + $filter('encode')(ctrl.siteReport.serviceCode)].push(selectedRow);
									});
									if (!ctrl.site.siteReportsTmp || ctrl.site.siteReportsTmp.length == 0)
										ctrl.site.siteReportsTmp = ctrl.site['siteReports' + $filter('encode')(ctrl.siteReport.serviceCode)] || [];
									
								},
								'close' : function(){
									rejected();
								}
							}				   
						});	
				});
			};
			
			ctrl.editReport = function(row) {
				var params = {};
				var _selectedCompanyReport = row.entity;
				params.companyRpt = angular.copy(_selectedCompanyReport);
				params.companyRpt.filterReportCodes = [];
				params.companyRpt.companyCode =  $filter('encode')(ctrl.site.siteCode);	//siteCode
				angular.forEach(ctrl.site.siteReports, function(report, index) {
					params.companyRpt.filterReportCodes.push(report.reportCode);
				});
				modalService.openCustomDialogs({
				   'title': 'Site Report',
				   'dialogsModule' : 'cda.company.rptEdit',
				   'params': params,
				   'btnCallback' : {
						'ok' : function(report) {
							if (!ctrl.site.siteReports) {								
								ctrl.site.siteReports = [];
							}
							if (!(report.dataStatus == 'C' || report.dataStatus == 'U')) {
								if (updateProcessFlag) {
									report.dataStatus = 'U';
								} else {
									report.dataStatus = 'C';
								}
							}
							report.companyCode = ctrl.site.siteCode;//need has encode
							report.report.reportName = _selectedCompanyReport.report.reportName || report.reportName;
							report.report.reportTitle = _selectedCompanyReport.report.reportTitle || report.reportTitle;
							report.report.reportSubtitle = _selectedCompanyReport.report.reportSubtitle || report.reportSubtitle;
							report.report.reportMode = _selectedCompanyReport.report.reportMode || report.reportMode;
							_selectedCompanyReport.report.serviceCode = report.serviceCode;
							angular.extend(_selectedCompanyReport, report);
						}
					}				   
				});	
			};
			
			ctrl.viewReport = function(row) {
				var params = {};
				params.companyRpt = row.entity;
				if (ctrl.siteOld && ctrl.siteOld.siteReports) {
					var oldModel4SelectedRow;
					angular.forEach(ctrl.siteOld.siteReports, function(siteReport, index) {
						if (siteReport.companyRptId == params.companyRpt.companyRptId) {
							oldModel4SelectedRow = siteReport;
						}
					});
					params.companyRptOld = oldModel4SelectedRow;
				}
				modalService.openCustomDialogs({
				   'title': 'Site Report',
				   'dialogsModule' : 'cda.company.rptView',
				   'params': params,
				   'btnCallback' : {
						'ok' : function(report) {			
						}
					}				   
				});	
			};
			
			ctrl.removeReport = function(currRow) {
				// delete from ctrl.site.siteReports
				angular.forEach(ctrl.selectedSiteReports, function(selectedSiteRpt, key) {
					angular.forEach(ctrl.site.siteReports, function(siteReport, index) {
						if (siteReport.$$hashKey == selectedSiteRpt.$$hashKey) {
							if (siteReport.dataStatus =='C') {
								ctrl.site.siteReports.splice(index, 1);
							} else {
								siteReport.dataStatus = 'D';
							}
						}
					});
				});
			};
		}
		
		function initPageCallback(ctrl) {
			ctrl.addContact = addContact;
			ctrl.editContact = editContact;
			ctrl.viewContact = viewContact;
			ctrl.removeContact = angular.noop;
			ctrl.addService = addService;
			ctrl.editService = editService;
			ctrl.viewService = viewService;
			ctrl.removeService = angular.noop;
			ctrl.addCompany = addCompany;
			ctrl.openNotify = openNotify;
			ctrl.viewNotify = viewNotify;
			ctrl.addNotify = addNotify;
			ctrl.openEvent = openEvent;
			ctrl.viewEvent = viewEvent;
			ctrl.addEdiFileDeli = addEdiFileDeli;
			ctrl.addSiteProp = addSiteProp;
			ctrl.removeSiteProp = removeSiteProp;
			//add siteAddr
			ctrl.addAddr = addAddr;
			ctrl.editAddr = editAddr;
			ctrl.viewAddr = viewAddr;
			ctrl.removeAddr = angular.noop;
			
			ctrl.moreAddress ={};
			ctrl.moreAddress.activeIndex = 0;
			ctrl.redirrctToAddress = function(){
				ctrl.moreAddress.activeIndex = 9;
			}
			
			function addAddr (row) {
				return $q(function(resolved, rejected){
					modalService.openCustomDialogs({
						   'title': 'Site Address',
						   'dialogsModule' : 'cda.company.addrEdit',
						   'params': {},
						   'btnCallback' : {
								'ok' : function(address) {		
									if (!ctrl.site.siteAddrs) {								
										ctrl.site.siteAddrs = [];
									}  
									address.dataStatus = 'C';
									angular.extend(row, address);
									resolved();
								},
							    'close' : function(){
								   rejected();
							    }
							}				   
						});	
				});
			};
			function editAddr (row) {
				var params = {};
				params.companyAddr = row.entity;
				modalService.openCustomDialogs({
				   'title': 'Site Address',
				   'dialogsModule' : 'cda.company.addrEdit',
				   'params':  params,
				   'btnCallback' : {
						'ok' : function(address) {			
							row.entity.dataStatus = (address.dataStatus == 'C' ? 'C':'U');
						}
					}				   
				});	
			}
			function viewAddr (row) {
				var params = {};
				// for show selected address on popup page
				params.companyAddr = row.entity;
				if (ctrl.siteOld && ctrl.siteOld.siteAddrs) {
					var oldModel4SelectedRow;
					angular.forEach(ctrl.siteOld.siteAddrs, function(address, index) {
						if (address.companyAddrId == params.companyAddr.companyAddrId) {
							oldModel4SelectedRow = address;
						}
					});
					params.companyAddrOld = oldModel4SelectedRow;
				}
				modalService.openCustomDialogs({
				   'title': 'Company Address',
				   'dialogsModule' : 'cda.company.addrView',
				   'params':  params,
				   'btnCallback' : {
						'ok' : function(address) {			
						}
					}				   
				});	
			}
			
			ctrl.glPostMgrChanged = function() {
				glPostMgrChanged(ctrl.site, ctrl.layoutConfig.formConfigs);
			};
			ctrl.ediProfileTypeChanged = function() {
				ediProfileTypeChanged(ctrl.site);
			};
			ctrl.ediFileDeliChanged = ediFileDeliChanged;
			ctrl.ediFileDeliCompanyTypeChanged = ediFileDeliCompanyTypeChanged;
			ctrl.moreDataLookup = moreDataLookup;
			
			function addContact(row) {
				return $q(function(resolved, rejected) {
					modalService.openCustomDialogs({
						'dialogsModule' : 'cda.company.contactEdit',
						'params' : {
							'companyCode' : ctrl.site.company.companyCode
						},
						'btnCallback' : {
							'ok' : function(contactCtrl) {
								if (!ctrl.site.company) {
									ctrl.site.company = {};
								}
								if (!ctrl.site.company.companyContacts) {
									ctrl.site.company.companyContacts = [];
								}
								contactCtrl.companyContact.dataStatus = 'C';
								angular.extend(row, contactCtrl.companyContact);
								row.companyCode = ctrl.site.company.companyCode;
								resolved();
							},
							'close' : function() {
								rejected();
							}
						}
					});
				});
			}
			function editContact(row) {
				modalService.openCustomDialogs({
					'dialogsModule' : 'cda.company.contactEdit',
					'params' : row.entity,
					'btnCallback' : {
						'ok' : function(contactCtrl) {
							// TODU: error logic
							angular.forEach(row, function(selectedItem, index) {
								angular.forEach(ctrl.site.company.companyContacts, function(item, i) {
									if (selectedItem.$$hashKey == item.$$hashKey && ctrl.site.company.companyContacts[i].contactId > 0) {
										ctrl.site.company.companyContacts[i].dataStatus = 'U';
									}
								});
							});
						},
					}
				});
			}
			function viewContact(row) {
				row.entity.readOnly = true;
				modalService.openCustomDialogs({
					'dialogsModule' : 'cda.company.contactEdit',
					'params' : row.entity
				});
			}
			function viewService(row) {
				var service = row.entity;
				if (service) {
					if (service.companyServCmpts && service.companyServCmpts.length) {
						modalService.openCustomDialogs({
							'title' : 'Service Lookup',
							'dialogsModule' : 'cda.componentView',
							'params' : {
								service : service
							}
						});
					} else {
						authService.getCompanyService(service).then(function(response) {
							service = response.data;
							modalService.openCustomDialogs({
								'title' : 'Service Lookup',
								'dialogsModule' : 'cda.componentView',
								'params' : {
									service : service
								}
							});
						});
					}
				}
			}
			function editService(row) {
				return $q(function(resolved, rejected) {
					var service = angular.copy(row.entity);
					if (service) {
						if (service.dataStatus == 'D') {
							modalService.openErrorDialogs({
								messages : [ "js.info.common.item-status-not-verified" ]
							});
							return;
						}
						modalService.openCustomDialogs({
							'title' : 'Service Lookup',
							'dialogsModule' : 'cda.component',
							'params' : {
								multiSelect : true,
								service : row.entity
							},
							'btnCallback' : {
								'ok' : function(service) {
									if (!angular.equals(service, row.entity)) {
										row.entity.dataStatus = (row.entity.dataStatus == 'C' ? 'C' : 'U');
										row.entity.companyServCmpts = service.companyServCmpts;
									}
								},
								'close' : function() {
									rejected();
								}
							}
						});
					}
				});
			}
			function addService(row) {
				return $q(function(resolved, rejected) {
					var existServices = ctrl.site.company.services;
					modalService.openCustomDialogs({
						'title' : 'Service Lookup',
						'dialogsModule' : 'cda.component',
						'params' : {
							multiSelect : true,
							services : existServices
						},
						'btnCallback' : {
							'ok' : function(service) {
								if (!ctrl.site.company.services) {
									ctrl.site.company.services = [];
								}
								var i, item;
								for (i = 0; i < ctrl.site.company.services.length; i++) {
									item = ctrl.site.company.services[i];
									if (item.serviceCode == service.serviceCode) {
										modalService.openErrorDialogs({
											messages : [ "js.info.common.item-hadbeen-added" ]
										});
										rejected();
										return;
									}
								}
								service.dataStatus = 'C';
								angular.extend(row, service);
								resolved();
							},
							'close' : function() {
								rejected();
							}
						}
					});
				});
			}
			function addCompany(row) {
				return $q(function(resolved, rejected) {
					var filterCompanyCodes = [];
					ctrl.site.company.subCompanies = ctrl.site.company.subCompanies || [];
					for (var i = 0; i < ctrl.site.company.subCompanies.length; i++) {
						filterCompanyCodes.push(ctrl.site.company.subCompanies[i].companyCode);
					}
					modalService.openCustomDialogs({
						'title' : 'Company Lookup',
						'dialogsModule' : 'cda.company',
						'params' : {
							companyCode : ctrl.site.siteCode,
							action : 'CREATE',
							filterCompanyCodes : filterCompanyCodes,
							lookupFlag : "Y"
						}, // add for not sysadm cooperation
						'btnCallback' : {
							'ok' : function(subCompanies) {
								if (!subCompanies || subCompanies.length == 0) {
									modalService.openErrorDialogs({
										messages : [ 'title.dialogs.info.norecsel' ]
									});
									return false;
								}
								var subcompany = subCompanies[0];
								if (!ctrl.site.company.subCompanies) {
									ctrl.site.company.subCompanies = [];
								}
								var exist = false;
								for (var i = 0; i < ctrl.site.company.subCompanies.length; i++) {
									var item = ctrl.site.company.subCompanies[i];
									if (item.companyCode == subcompany.companyCode) {
										exist = true;
										break;
									}
								}
								if (!exist) {
									subcompany.childCompanyCode = subcompany.companyCode;
									subcompany.dataStatus = 'C';
									ctrl.site.company.subCompanies.push(subcompany);
								}
							},
							'close' : function() {
								rejected();
							}
						}

					});
				});
			}
			function openNotify(row) {
				if (row.entity) {
					var serviceParam = [];
					for (var i = 0; i < ctrl.site.company.services.length; i++) {
						if (ctrl.site.company.services[i] && ctrl.site.company.services[i].dataStatus != 'D') {
							serviceParam.push(ctrl.site.company.services[i]);
						}
					}
					modalService.openCustomDialogs({
						'title' : 'Notification',
						'dialogsModule' : 'cda.companynotify.popupedit',
						'params' : {
							notify : row.entity,
							services : serviceParam
						},
						'btnCallback' : {
							'ok' : function(companyNotify) {
								row.entity = companyNotify;
								row.entity.dataStatus = (row.entity.dataStatus == 'C' ? 'C' : 'U');
							}
						}
					});
				}
			}
			function viewNotify(row) {
				if (row.entity) {
					modalService.openCustomDialogs({
						'title' : 'Notification',
						'dialogsModule' : 'cda.companynotify.popupview',
						'params' : {
							notify : row.entity,
							services : ctrl.site.company.services
						},
						'btnCallback' : {
							'ok' : function(companyNotify) {
							}
						}

					});
				}
			}
			function addNotify(row) {
				return $q(function(resolved, rejected) {
					var serviceParam = [];
					if (ctrl.site.company && ctrl.site.company.services) {
						for (var i = 0; i < ctrl.site.company.services.length; i++) {
							// if (ctrl.site.company.services[i] && ctrl.site.company.services[i].dataStatus != 'D') {
							serviceParam.push(ctrl.site.company.services[i]);
							// }
						}
					}
					modalService.openCustomDialogs({
						'title' : 'Notification',
						'dialogsModule' : 'cda.companynotify.popupedit',
						'params' : {
							services : serviceParam
						},
						'btnCallback' : {
							'ok' : function(companyNotify) {
								if (!ctrl.site.company.notifies) {
									ctrl.site.company.notifies = [];
								}
								companyNotify.dataStatus = 'C';
								ctrl.site.company.notifies.push(companyNotify);
							},
							'close' : function() {
								rejected();
							}
						}

					});
				});
			}
			function openEvent(row) {
				var notifyTpls = ctrl.site.notifyTpls || [];
				if (row.entity ) {
					var params = row.entity || [];
					if (params) {
						params.siteCode = ctrl.site.siteCode;
					}
					modalService.openCustomDialogs({
						'title' : 'Bank Event Document Template',
						'dialogsModule' : 'cda.notifydoc.editpopup',
						'params' : {
							event : params,
							notifyTpls : notifyTpls,
							validation : ctrl.validatorConfig.notifyTpls
						},
						'btnCallback' : {
							'ok' : function(notifyTpl) {
								var exist = false;
								// selectedNotifyRows[0] = companyNotify;
//								if (notifyTpl && notifyTpl.overrideFlag == 'Y' && notifyTpl.dirty) {
								if (notifyTpl && notifyTpl.dirty) {
									notifyTpl.eventCode = row.entity.eventCode;
									notifyTpl.dataStatus = 'U';
									for (var i = 0; i < notifyTpls.length; i++) {
										if ($filter('encode')(notifyTpls[i].eventCode) == $filter('encode')(notifyTpl.eventCode) 
												&& $filter('encode')(notifyTpls[i].localeCode) == $filter('encode')(notifyTpl.localeCode)
												&& $filter('encode')(notifyTpls[i].notifyType) == $filter('encode')(notifyTpl.notifyType) ){
											notifyTpls[i] = notifyTpl;
											exist = true;
											break;
										}
									}
									if (!exist) {
										if (!ctrl.site.notifyTpls) {
											ctrl.site.notifyTpls = [];
										}
										ctrl.site.notifyTpls.push(notifyTpl);
									}
								}
							}
						}

					});
				}
			}
			function viewEvent(row) {
				var notifyTpls = ctrl.site.notifyTpls || [];
				if (row.entity ) {
					var params = row.entity || [];
					if (params) {
						params.siteCode = ctrl.site.siteCode;
					}
					var event, eventCode = row.entity.eventCode;
					for (var i = 0; i < notifyTpls.length; i++) {
						if ($filter('encode')(notifyTpls[i].eventCode) == $filter('encode')(eventCode)) {
							event = notifyTpls[i];
							break;
						}
					}
					if (event) {
						event.siteCode = ctrl.site.siteCode;
					}
					modalService.openCustomDialogs({
						'title' : 'Bank Event Document Template',
						'dialogsModule' : 'cda.notifydoc.viewpopup',
						'params' : {
							event : params,
							notifyTpls : notifyTpls
						},
						'btnCallback' : {
							'ok' : function(notifyTpl) {
							}
						}
					});
				}
			}
			function addEdiFileDeli() {
				return $q(function(resolved, rejected) {
					if (ctrl.site.company.companyEdiProfile && !ctrl.site.company.companyEdiProfile.companyEdiFileDelis) {
						ctrl.site.company.companyEdiProfile.companyEdiFileDelis = [];
					}
					ctrl.site.company.companyEdiProfile.companyEdiFileDelis.push({
						fileType : '*',
						companyType : '*',
						deliFlag : 'Y',
						deliSvcName : '',
						filenameFixFlag : 'N',
						filenamePrefix : '',
						filenameSuffix : '',
						filenameMiddle : '',
						deliPriority : 4,
						dataStatus : 'C'
					});
				});
			}
			function addSiteProp(row) {
				var corProf;
				if (ctrl.selectedDynaParmAvaiRows != null) {
					if (!ctrl.site.dynamicParams) {
						ctrl.site.dynamicParams = {};
					}
					angular.forEach(ctrl.selectedDynaParmAvaiRows, function(selectedDynaParmAvai, key) {
						angular.forEach(ctrl.availableProperties, function(availableProperty, index) {
							if (availableProperty.$$hashKey == selectedDynaParmAvai.$$hashKey) {
								ctrl.availableProperties.splice(index, 1);
								// some new add not in site.dynamicParams, so need put it in
								if (!ctrl.site.dynamicParams[availableProperty.name] || !ctrl.site.dynamicParams[availableProperty.name].value) {
									ctrl.site.dynamicParams[availableProperty.name] = availableProperty;
									angular.merge(availableProperty, availableProperty.dynamicParameter);
								}
								// change
								corProf = angular.copy(availableProperty);
								corProf.dynamicParams = {};
								corProf.dynamicParams[availableProperty.name] = availableProperty;
								ctrl.site.siteProps.push(corProf);
							}
						});
					});
					ctrl.selectedDynaParmAvaiRows = [];
				} else {
					modalService.openErrorDialogs({
						messages : [ 'title.dialogs.info.norecsel' ]
					});
				}
			}
			function removeSiteProp() {
				if (ctrl.selectedDynaParmSeleRows != null) {
					angular.forEach(ctrl.selectedDynaParmSeleRows, function(selectedParam, key) {
						angular.forEach(ctrl.site.siteProps, function(siteProp, index) {
							if (siteProp.$$hashKey == selectedParam.$$hashKey) {
								// clear for delete,
								// some new add prop or exist prop, then remove, also commit to server but value is empty, in server to check delete/do nothing
								delete siteProp.dynamicParams[siteProp.name].value;
								ctrl.site.siteProps.splice(index, 1);
								ctrl.availableProperties.push(siteProp);
							}
						});
					});
					ctrl.selectedDynaParmSeleRows = [];
				} else {
					modalService.openErrorDialogs({
						messages : [ 'title.dialogs.info.norecsel' ]
					});
				}
			}
			function moreDataLookup(){
				modalService.openCustomDialogs({
					'title': '',
					'dialogsModule' : 'cda.siteMoreDataLookup',
					'params': ctrl.site,
					'btnCallback' : {
						'ok' : function(resultList) {
							ctrl.setMoreData(ctrl.site, resultList);
						}
					}	
				});
			}
		}
		
		function initTableConfig(scope, ctrl, layoutConfig) {
			var generalConfig, contactConfig, serviceConfig, subCompanyConfig, notifyConfig, notifyDocConfig, ediFileDeliConfig, custProfileConfig, 
			siteAddrConfig, siteReportConfig;
			if (!layoutConfig) {
				return;
			}
			generalConfig = layoutConfig.formConfigs.general;
			contactConfig = layoutConfig.formConfigs.contact;
			serviceConfig = layoutConfig.formConfigs.service;
			subCompanyConfig = layoutConfig.formConfigs.subcompany;
			notifyConfig = layoutConfig.formConfigs.notify;
			notifyDocConfig = layoutConfig.formConfigs.notifydoc;
			ediFileDeliConfig = layoutConfig.formConfigs.ediFileDeli;
			custProfileConfig = layoutConfig.formConfigs.custProfile;
			siteAddrConfig = layoutConfig.formConfigs.address;
			siteReportConfig = layoutConfig.formConfigs.report;
//			if(ctrl.validatorConfig) ctrl.layoutConfig.formConfigs.address.tableConfigs.table.validatorConfig = ctrl.validatorConfig.siteAddrs;
			
			ctrl.reportInnerGridOptions = gridService.createInnerGridOptions(scope, siteReportConfig.tableConfigs.table, reportRowSelectionChanged);
			ctrl.reportInnerGridOptions.data = 'vm.site.siteReportsTmp';
			ctrl.reportInnerGridOptions.verifyData = 'vm.siteOld.siteReportsTmp';
			
			ctrl.addressInnerGridOptions = gridService.createInnerGridOptions(scope, siteAddrConfig.tableConfigs.table, addressRowSelectionChanged);
			ctrl.addressInnerGridOptions.data = 'vm.site.siteAddrs';
			ctrl.addressInnerGridOptions.verifyData = 'vm.siteOld.siteAddrs';
			
			ctrl.contactInnerGridOptions = gridService.createInnerGridOptions(scope, contactConfig.tableConfigs.table, contractSelected);
			ctrl.contactInnerGridOptions.data = 'vm.site.company.companyContacts';
			ctrl.contactInnerGridOptions.verifyData = 'vm.siteOld.company.companyContacts';

			ctrl.serviceGridOptions = gridService.createInnerGridOptions(scope, serviceConfig.tableConfigs.table, serviceSelected);
			ctrl.serviceGridOptions.data = 'vm.site.company.services';
			ctrl.serviceGridOptions.verifyData = 'vm.siteOld.company.services';

			ctrl.subcompanyGridOptions = gridService.createInnerGridOptions(scope, subCompanyConfig.tableConfigs.table, subcompanySelected);
			ctrl.subcompanyGridOptions.data = 'vm.site.company.subCompanies';
			ctrl.subcompanyGridOptions.verifyData = 'vm.siteOld.company.subCompanies';

			ctrl.notifyGridOptions = gridService.createInnerGridOptions(scope, notifyConfig.tableConfigs.table, notifySelected);
			ctrl.notifyGridOptions.data = 'vm.site.company.notifies';
			ctrl.notifyGridOptions.verifyData = 'vm.siteOld.company.notifies';

			ctrl.eventGridOptions = gridService.createGridOptions(scope, notifyDocConfig.tableConfigs.table, eventPaginationChanged, eventSelected, eventSortChanged);
			ctrl.eventGridOptions.data = 'vm.eventSearchCriteria.list';
			ctrl.eventGridOptions.enableRowHeaderSelection = false;
			ctrl.eventSearchCriteria = ctrl.eventGridOptions.defaultSearchCriteria;

			if(ctrl.validatorConfig && ctrl.validatorConfig.company && ctrl.validatorConfig.company.companyEdiProfile) {
				ediFileDeliConfig.tableConfigs.table.validatorConfig = ctrl.validatorConfig.company.companyEdiProfile.companyEdiFileDelis;
			}
			ctrl.ediFileDeliInnerGridOptions = gridService.createInnerGridOptions(scope, ediFileDeliConfig.tableConfigs.table, ediFileDeliSelected);
			ctrl.ediFileDeliInnerGridOptions.data = 'vm.site.company.companyEdiProfile.companyEdiFileDelis';
			ctrl.ediFileDeliInnerGridOptions.verifyData = 'vm.siteOld.company.companyEdiProfile.companyEdiFileDelis';
			
			ctrl.selectedPropertyInnerGridOptions = gridService.createInnerGridOptions(scope, custProfileConfig.tableConfigs.tableSele, dynaParmSeleSelected);
			ctrl.selectedPropertyInnerGridOptions.data = 'vm.site.siteProps';
			ctrl.selectedPropertyInnerGridOptions.multiSelect = true;
			if (custProfileConfig.tableConfigs.tableAvai) {
				ctrl.availablePropertyInnerGridOptions = gridService.createInnerGridOptions(scope, custProfileConfig.tableConfigs.tableAvai, dynaParmAvaiSelected);
				ctrl.availablePropertyInnerGridOptions.data = 'vm.availableProperties';
				ctrl.availablePropertyInnerGridOptions.multiSelect = true;
				ctrl.hasAvailablePropertyInnerGrid = 'Y';
			}
			
			function reportRowSelectionChanged(eventRow, selectedRows) {
				ctrl.selectedSiteReports = selectedRows;
			}
			function addressRowSelectionChanged(eventRow, selectedRows) {
				ctrl.selectedSiteAddrs = selectedRows;
			}
			function contractSelected(eventRow, selectedRows) {
				ctrl.selectedContacts = selectedRows;
			}
			function serviceSelected(eventRow, selectedRows) {
				ctrl.selectedServices = selectedRows;
			}
			function subcompanySelected(eventRow, selectedRows) {
				ctrl.selectedCompanies = selectedRows;
			} 
			function notifySelected(eventRow, selectedRows) {
				ctrl.selectedNotifies = selectedRows;
			}
			function eventSelected(eventRow, selectedRows) {
				ctrl.selectedEvents = selectedRows;
			}
			function ediFileDeliSelected(eventRow, selectedRows) {
				ctrl.selectedEdiFileDelis = selectedRows;
			}
			function dynaParmSeleSelected(eventRow, selectedRows) {
				ctrl.selectedDynaParmSeleRows = selectedRows;
			}
			function dynaParmAvaiSelected(eventRow, selectedRows) {
				ctrl.selectedDynaParmAvaiRows = selectedRows;
			}
			
			function eventPaginationChanged(pageNum, pageSize) {				
				ctrl.eventSearchCriteria.pageNum = pageNum;
				ctrl.eventSearchCriteria.pageSize = pageSize;
				ctrl.eventSearchCriteria.list = [];
				searchEvents(ctrl, ctrl.eventSearchCriteria);
			}
			function eventSortChanged(sortColumns) {
				ctrl.eventSearchCriteria.sortDirection = sortColumns[0] ? sortColumns[0].direction : '';
				ctrl.eventSearchCriteria.sortBy = sortColumns[0] ? sortColumns[0].sortBy : '';
				searchEvents(ctrl, ctrl.eventSearchCriteria);
			}
		}
		
		return {
			getLayoutConfig : getLayoutConfig,
			getLocaleCodesTwo : getLocaleCodesTwo,
			setLocaleOptions : setLocaleOptions,
			getLocaleOptions : getLocaleOptions,
			loadSiteOptions : loadSiteOptions,
			ediProfileTypeChanged : ediProfileTypeChanged,
			ediFileDeliChanged : ediFileDeliChanged,
			glPostMgrChanged : glPostMgrChanged,
			initEdiProfile : initEdiProfile,
			sortDynamicParamters : sortDynamicParamters,
			resetDynaProperties : resetDynaProperties,
			initSiteOptionData : initSiteOptionData,
			searchEvents : searchEvents,
			initReport : initReport,
			initPageCallback : initPageCallback,
			initTableConfig : initTableConfig,
			initSiteUserTheme : initSiteUserTheme,
			getCalendarCodes : getCalendarCodes,
			filterNotifyTpl : filterNotifyTpl
		};
	}
})(angular);
